package com.moviemetagetter.xml;

import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import com.moviemetagetter.model.Movie;

public class TagChimpXmlParser extends DefaultHandler {

	private List<Movie> movies;

	private StringBuffer buffer;

	private boolean inMovieTitle = false;
	private boolean inRating = false;
	private boolean inDirector = false;
	private boolean inProducer = false;
	private boolean inGenre = false;
	private boolean inScreenwriter = false;
	private boolean inActor = false;
	private boolean inShortDescription = false;
	private boolean inLongDescription = false;
	
	private Movie currentMovie;

	public TagChimpXmlParser(){
	}
	
	public List<Movie> parse(String xml){
		buffer = new StringBuffer();
		movies = new ArrayList<Movie>();
		
		StringReader reader = new StringReader(xml.trim());
		InputSource source = new InputSource(reader);
        SAXParserFactory factory = SAXParserFactory.newInstance();
        
        try {
            SAXParser saxParser = factory.newSAXParser();
            saxParser.parse( source, this );
        } catch (Throwable t) {
        	t.printStackTrace();
        }
        
        return movies;
	}
	
	public List<Movie> getMovies(){
		return movies;
	}
	
	@Override
	public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
		
		String eName = localName; // element name
		if ("".equals(eName))
			eName = qName; // namespaceAware = false

		if (eName.equals("movie")) {
			currentMovie = new Movie();
			movies.add(currentMovie);
		} else if (eName.equals("movieTitle")) {
			inMovieTitle = true;
		} else if (eName.equals("genre")) {
			inGenre = true;
		} else if (eName.equals("rating")) {
			inRating = true;
		} else if (eName.equals("director")) {
			inDirector = true;
		} else if (eName.equals("producer")) {
			inProducer = true;
		} else if (eName.equals("screenwriter")) {
			inScreenwriter = true;
		} else if (eName.equals("actor")) {
			inActor = true;
		} else if (eName.equals("shortDescription")) {
			inShortDescription = true;
		} else if (eName.equals("longDescription")) {
			inLongDescription = true;
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName) throws SAXException {
		
    	processBuffer();
		buffer = new StringBuffer();
		
		String eName = localName; // element name
		if ("".equals(eName))
			eName = qName; // namespaceAware = false

		if (eName.equals("movieTitle")) {
			inMovieTitle = false;
		} else if (eName.equals("genre")) {
			inGenre = false;
		} else if (eName.equals("rating")) {
			inRating = false;
		} else if (eName.equals("director")) {
			inDirector = false;
		} else if (eName.equals("producer")) {
			inProducer = false;
		} else if (eName.equals("screenwriter")) {
			inScreenwriter = false;
		} else if (eName.equals("actor")) {
			inActor = false;
		} else if (eName.equals("shortDescription")) {
			inShortDescription = false;
		} else if (eName.equals("longDescription")) {
			inLongDescription = false;
		}
	}

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		String s = new String(ch, start, length);
        s = s.trim();
        if(s.equals("")) return;
        
        buffer.append(s);
	}

	private void processBuffer() {
		if(buffer.length() > 0){
			if(inMovieTitle){
				currentMovie.setTitle(buffer.toString());
			}else if(inActor){
				currentMovie.getActors().add(buffer.toString());
			}else if(inDirector){
				currentMovie.getDirectors().add(buffer.toString());
			}else if(inGenre){
				currentMovie.setGenre(buffer.toString());
			}else if(inLongDescription){
				currentMovie.setLongDescription(buffer.toString());
			}else if(inProducer){
				currentMovie.getProducers().add(buffer.toString());
			}else if(inRating){
				currentMovie.setRating(buffer.toString());
			}else if(inScreenwriter){
				currentMovie.getScreenwriters().add(buffer.toString());
			}else if(inShortDescription){
				currentMovie.setShortDescription(buffer.toString());
			}
		}
	}
}
